const express = require('express');
const { body, validationResult } = require('express-validator');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const mysql = require('mysql2/promise');
const path = require('path');
const fs = require('fs');

const Admin = require('../models/Admin');
const User = require('../models/User');
const Clue = require('../models/Clue');
const db = require('../config/database');
const {
  generateToken,
  authenticateToken,
  requireRole,
  refreshToken,
  checkAdminStatus,
  requireSelfOrSuperAdmin
} = require('../middleware/auth');

const router = express.Router();

// ======================== 认证相关 ========================

/**
 * @route POST /api/admin/login
 * @desc 管理员登录
 * @access Public
 */
router.post('/login', [
  body('username').notEmpty().withMessage('用户名不能为空'),
  body('password').notEmpty().withMessage('密码不能为空')
], async (req, res) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({
        code: 400,
        message: '登录信息验证失败',
        errors: errors.array(),
        timestamp: Date.now()
      });
    }

    const { username, password } = req.body;
    const clientIP = req.ip || req.connection.remoteAddress;

    // 查找管理员
    const admin = await Admin.findByUsername(username);
    if (!admin) {
      return res.status(401).json({
        code: 401,
        message: '用户名或密码错误',
        timestamp: Date.now()
      });
    }

    // 检查账户状态
    if (!admin.is_active) {
      return res.status(401).json({
        code: 401,
        message: '账户已被禁用',
        timestamp: Date.now()
      });
    }

    // 验证密码
    const isValidPassword = await admin.validatePassword(password);
    if (!isValidPassword) {
      return res.status(401).json({
        code: 401,
        message: '用户名或密码错误',
        timestamp: Date.now()
      });
    }

    // 更新登录信息
    await admin.updateLoginInfo(clientIP);

    // 生成JWT Token
    const token = generateToken({
      id: admin.id,
      username: admin.username,
      role: admin.role
    });

    // 记录操作日志
    await admin.logAction('login', 'auth', '管理员登录系统', {
      ip: clientIP,
      userAgent: req.get('User-Agent')
    });

    res.json({
      code: 200,
      message: '登录成功',
      data: {
        token,
        expires_in: parseInt(process.env.JWT_EXPIRES_IN || '7200'),
        user_info: admin.getSafeInfo()
      },
      timestamp: Date.now()
    });

  } catch (error) {
    console.error('管理员登录失败:', error);
    res.status(500).json({
      code: 500,
      message: '登录失败，请稍后重试',
      timestamp: Date.now()
    });
  }
});

/**
 * @route POST /api/admin/refresh-token
 * @desc 刷新Token
 * @access Private
 */
router.post('/refresh-token', refreshToken);

/**
 * @route POST /api/admin/logout
 * @desc 退出登录
 * @access Private
 */
router.post('/logout', authenticateToken, async (req, res) => {
  try {
    const admin = await Admin.findById(req.admin.id);
    if (admin) {
      await admin.logAction('logout', 'auth', '管理员退出系统', {
        ip: req.ip,
        userAgent: req.get('User-Agent')
      });
    }

    res.json({
      code: 200,
      message: '退出成功',
      timestamp: Date.now()
    });
  } catch (error) {
    console.error('退出失败:', error);
    res.status(500).json({
      code: 500,
      message: '退出失败',
      timestamp: Date.now()
    });
  }
});

// ======================== 线索管理 ========================

/**
 * @route GET /api/admin/clues
 * @desc 获取线索列表
 * @access Private (operator+)
 */
router.get('/clues', authenticateToken, requireRole('operator'), async (req, res) => {
  try {
    const options = {
      page: parseInt(req.query.page) || 1,
      pageSize: parseInt(req.query.page_size) || 20,
      category: req.query.category,
      status: req.query.status,
      startDate: req.query.start_date,
      endDate: req.query.end_date,
      keyword: req.query.keyword,
      handlerId: req.query.handler_id,
      priority: req.query.priority
    };

    const result = await Clue.getList(options);

    res.json({
      code: 200,
      message: 'success',
      data: result,
      timestamp: Date.now()
    });

  } catch (error) {
    console.error('获取线索列表失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取线索列表失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route GET /api/admin/clues/export
 * @desc 导出线索数据
 * @access Private (operator+)
 */
router.get('/clues/export', async (req, res) => {
  try {
    // 支持通过URL参数或Header传递token
    let token = req.headers.authorization?.replace('Bearer ', '');
    if (!token && req.query.token) {
      token = req.query.token;
    }

    if (!token) {
      return res.status(401).json({
        code: 401,
        message: '未提供认证令牌',
        timestamp: Date.now()
      });
    }

    // 验证token
    let decoded;
    try {
      decoded = jwt.verify(token, process.env.JWT_SECRET);
    } catch (error) {
      return res.status(401).json({
        code: 401,
        message: '认证令牌无效',
        timestamp: Date.now()
      });
    }

    // 检查用户权限
    const admin = await Admin.findById(decoded.id);
    if (!admin || !admin.is_active) {
      return res.status(401).json({
        code: 401,
        message: '用户不存在或已被禁用',
        timestamp: Date.now()
      });
    }

    if (!['operator', 'admin', 'super_admin'].includes(admin.role)) {
      return res.status(403).json({
        code: 403,
        message: '权限不足',
        timestamp: Date.now()
      });
    }

    const {
      format = 'excel',
      category,
      status,
      priority,
      keyword,
      start_date: startDate,
      end_date: endDate,
      clue_ids: clueIds
    } = req.query;

    console.log('导出参数:', req.query);

    // 构建查询参数，过滤空值
    const exportOptions = {
      page: 1,
      pageSize: 10000 // 导出时获取大量数据
    };

    // 如果提供了线索ID列表，则按ID导出
    if (clueIds && clueIds.trim()) {
      const idsArray = clueIds.split(',').map(id => parseInt(id.trim())).filter(id => !isNaN(id));
      if (idsArray.length > 0) {
        exportOptions.clueIds = idsArray;
        console.log(`按ID导出，共 ${idsArray.length} 条线索:`, idsArray);
      }
    } else {
      // 否则使用筛选条件
      if (category && category.trim()) exportOptions.category = category.trim();
      if (status && status.trim()) exportOptions.status = status.trim();
      if (priority && priority.trim()) exportOptions.priority = priority.trim();
      if (keyword && keyword.trim()) exportOptions.keyword = keyword.trim();
      if (startDate && startDate.trim()) exportOptions.startDate = startDate.trim();
      if (endDate && endDate.trim()) exportOptions.endDate = endDate.trim();
    }

    // 获取线索数据
    const result = await Clue.getList(exportOptions);
    const clues = result.list || [];

    console.log(`准备导出 ${clues.length} 条线索数据，格式: ${format}`);

    if (clues.length === 0) {
      return res.status(400).json({
        code: 400,
        message: '没有找到符合条件的数据',
        timestamp: Date.now()
      });
    }

    // 记录操作日志
    if (admin) {
      await admin.logAction('export', 'clues', `导出线索数据 ${clues.length} 条`, {
        format,
        filters: exportOptions,
        count: clues.length
      });
    }

    if (format === 'excel') {
      await exportToExcel(res, clues);
    } else {
      await exportToCSV(res, clues);
    }

  } catch (error) {
    console.error('导出线索数据失败:', error);

    // 如果响应还没有发送，发送错误响应
    if (!res.headersSent) {
      res.status(500).json({
        code: 500,
        message: '导出失败，请稍后重试',
        error: process.env.NODE_ENV === 'development' ? error.message : undefined,
        timestamp: Date.now()
      });
    }
  }
});

// Excel导出函数（使用XML格式）
async function exportToExcel(res, clues) {
  try {
    const headers = [
      '线索编号', '标题', '分类', '状态', '优先级', '举报人', '举报人电话',
      '事件时间', '事件地点', '嫌疑人信息', '线索内容', '处理人', '处理意见',
      '提交时间', '更新时间', '查看次数', '附件数量'
    ];

    let xml = `<?xml version="1.0" encoding="UTF-8"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40">
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
<Created>${new Date().toISOString()}</Created>
</DocumentProperties>
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Bottom"/>
<Borders/>
<Font ss:FontName="宋体" x:CharSet="134" ss:Size="11" ss:Color="#000000"/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
<Style ss:ID="s62">
<Font ss:FontName="宋体" x:CharSet="134" ss:Size="11" ss:Color="#000000" ss:Bold="1"/>
<Interior ss:Color="#E6E6FA" ss:Pattern="Solid"/>
</Style>
</Styles>
<Worksheet ss:Name="线索数据">
<Table ss:ExpandedColumnCount="${headers.length}" ss:ExpandedRowCount="${clues.length + 1}" x:FullColumns="1" x:FullRows="1">`;

    // 添加表头
    xml += '<Row ss:AutoFitHeight="0" ss:StyleID="s62">';
    headers.forEach(header => {
      xml += `<Cell><Data ss:Type="String">${escapeXml(header)}</Data></Cell>`;
    });
    xml += '</Row>';

    // 添加数据行
    clues.forEach(clue => {
      xml += '<Row ss:AutoFitHeight="0">';
      xml += `<Cell><Data ss:Type="String">${escapeXml(clue.clue_no || '')}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="String">${escapeXml(clue.title || '')}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="String">${escapeXml(clue.category || '')}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="String">${escapeXml(getStatusText(clue.status) || '')}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="String">${escapeXml(getPriorityText(clue.priority) || '')}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="String">${escapeXml(clue.is_anonymous ? '匿名举报' : (clue.reporter_name || ''))}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="String">${escapeXml(clue.is_anonymous ? '匿名' : (clue.reporter_phone || ''))}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="String">${escapeXml(clue.incident_time ? formatDate(clue.incident_time) : '')}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="String">${escapeXml(clue.incident_location || '')}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="String">${escapeXml(clue.suspect_info || '')}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="String">${escapeXml(clue.content || '')}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="String">${escapeXml(clue.handler_name || '')}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="String">${escapeXml(clue.handle_note || '')}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="String">${escapeXml(formatDate(clue.created_at) || '')}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="String">${escapeXml(formatDate(clue.updated_at) || '')}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="Number">${clue.view_count || 0}</Data></Cell>`;
      xml += `<Cell><Data ss:Type="Number">${clue.attachment_count || 0}</Data></Cell>`;
      xml += '</Row>';
    });

    xml += '</Table></Worksheet></Workbook>';

    const filename = `线索数据导出_${new Date().toISOString().split('T')[0]}.xls`;

    res.setHeader('Content-Type', 'application/vnd.ms-excel; charset=utf-8');
    res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(filename)}"`);
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Pragma', 'no-cache');
    res.send(xml);
  } catch (error) {
    console.error('Excel导出失败:', error);
    throw error;
  }
}

// CSV导出函数
async function exportToCSV(res, clues) {
  try {
    const headers = [
      '线索编号',
      '标题',
      '分类',
      '状态',
      '优先级',
      '举报人',
      '举报人电话',
      '事件时间',
      '事件地点',
      '嫌疑人信息',
      '线索内容',
      '处理人',
      '处理意见',
      '提交时间',
      '更新时间',
      '查看次数',
      '附件数量'
    ];

    let csv = '\uFEFF'; // UTF-8 BOM
    csv += headers.join(',') + '\n';

    clues.forEach(clue => {
      const row = [
        escapeCsvField(clue.clue_no || ''),
        escapeCsvField(clue.title || ''),
        escapeCsvField(clue.category || ''),
        escapeCsvField(getStatusText(clue.status) || ''),
        escapeCsvField(getPriorityText(clue.priority) || ''),
        escapeCsvField(clue.is_anonymous ? '匿名举报' : (clue.reporter_name || '')),
        escapeCsvField(clue.is_anonymous ? '匿名' : (clue.reporter_phone || '')),
        escapeCsvField(clue.incident_time ? formatDate(clue.incident_time) : ''),
        escapeCsvField(clue.incident_location || ''),
        escapeCsvField(clue.suspect_info || ''),
        escapeCsvField(clue.content || ''),
        escapeCsvField(clue.handler_name || ''),
        escapeCsvField(clue.handle_note || ''),
        escapeCsvField(formatDate(clue.created_at) || ''),
        escapeCsvField(formatDate(clue.updated_at) || ''),
        clue.view_count || 0,
        clue.attachment_count || 0
      ];
      csv += row.join(',') + '\n';
    });

    const filename = `线索数据导出_${new Date().toISOString().split('T')[0]}.csv`;

    res.setHeader('Content-Type', 'text/csv; charset=utf-8');
    res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(filename)}"`);
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Pragma', 'no-cache');
    res.send(csv);
  } catch (error) {
    console.error('CSV导出失败:', error);
    throw error;
  }
}

// 导出辅助函数
function escapeCsvField(field) {
  if (!field) return '';
  const str = String(field);
  if (str.includes(',') || str.includes('"') || str.includes('\n')) {
    return `"${str.replace(/"/g, '""')}"`;
  }
  return str;
}

function escapeXml(str) {
  if (!str) return '';
  return String(str)
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');
}

function getStatusText(status) {
  const statusMap = {
    'pending': '待处理',
    'processing': '处理中',
    'completed': '已完成',
    'closed': '已关闭'
  };
  return statusMap[status] || status;
}

function getPriorityText(priority) {
  const priorityMap = {
    'high': '高',
    'medium': '中',
    'low': '低'
  };
  return priorityMap[priority] || '中';
}

function formatDate(dateString) {
  if (!dateString) return '';
  const date = new Date(dateString);
  return date.toLocaleString('zh-CN');
}

/**
 * @route GET /api/admin/clues/:id
 * @desc 获取线索详情
 * @access Private (operator+)
 */
router.get('/clues/:id', authenticateToken, requireRole('operator'), async (req, res) => {
  try {
    const { id } = req.params;
    const clue = await Clue.getDetail(id);

    if (!clue) {
      return res.status(404).json({
        code: 404,
        message: '线索不存在',
        timestamp: Date.now()
      });
    }

    // 增加查看次数
    await db.query('UPDATE clues SET view_count = view_count + 1 WHERE id = ?', [id]);

    res.json({
      code: 200,
      message: 'success',
      data: clue,
      timestamp: Date.now()
    });

  } catch (error) {
    console.error('获取线索详情失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取线索详情失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route GET /api/admin/clues/:id/attachments
 * @desc 获取线索附件列表
 * @access Private (operator+)
 */
router.get('/clues/:id/attachments', authenticateToken, requireRole('operator'), async (req, res) => {
  try {
    const { id } = req.params;
    
    // 验证线索是否存在
    const clue = await Clue.findById(id);
    if (!clue) {
      return res.status(404).json({
        code: 404,
        message: '线索不存在',
        timestamp: Date.now()
      });
    }

    // 获取附件列表
    const sql = `
      SELECT id, clue_id, file_name, file_path, file_size, file_type, file_extension, 
             upload_time, upload_ip, created_at
      FROM attachments 
      WHERE clue_id = ? AND is_deleted = 0 
      ORDER BY upload_time DESC
    `;
    
    const attachments = await db.query(sql, [id]);

    res.json({
      code: 200,
      message: 'success',
      data: attachments,
      timestamp: Date.now()
    });

  } catch (error) {
    console.error('获取线索附件失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取线索附件失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route PUT /api/admin/clues/:id/status
 * @desc 更新线索状态
 * @access Private (operator+)
 */
router.put('/clues/:id/status', authenticateToken, requireRole('operator'), [
  body('status').isIn(['pending', 'processing', 'completed', 'closed']).withMessage('无效的状态'),
], async (req, res) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({
        code: 400,
        message: '参数验证失败',
        errors: errors.array(),
        timestamp: Date.now()
      });
    }

    const clueId = parseInt(req.params.id);
    const { status, handler_id, handle_note } = req.body;

    const clue = await Clue.findById(clueId);
    if (!clue) {
      return res.status(404).json({
        code: 404,
        message: '线索不存在',
        timestamp: Date.now()
      });
    }

    const oldStatus = clue.status;
    const success = await clue.updateStatus(status, handler_id || req.admin.id, handle_note || '');

    if (success) {
      // 记录操作日志
      const admin = await Admin.findById(req.admin.id);
      if (admin) {
        await admin.logAction('update_clue_status', 'clue', `更新线索状态: ${clue.clue_no}`, {
          clue_id: clueId,
          old_status: oldStatus,
          new_status: status,
          ip: req.ip
        });

        // 记录详细的处理日志
        try {
          const processingLogSql = `
            INSERT INTO clue_processing_logs 
            (clue_id, admin_id, admin_name, action_type, old_value, new_value, processing_opinion, ip_address, user_agent)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
          `;

          await db.query(processingLogSql, [
            clueId,
            req.admin.id,
            admin.real_name,
            'status_change',
            oldStatus,
            status,
            handle_note || '',
            req.ip,
            req.get('User-Agent') || ''
          ]);
        } catch (logError) {
          console.error('记录处理日志失败:', logError);
          // 不影响主要流程，只记录错误
        }
      }

      res.json({
        code: 200,
        message: '状态更新成功',
        data: {
          old_status: oldStatus,
          new_status: status,
          processing_opinion: handle_note || ''
        },
        timestamp: Date.now()
      });
    } else {
      res.status(500).json({
        code: 500,
        message: '状态更新失败',
        timestamp: Date.now()
      });
    }

  } catch (error) {
    console.error('更新线索状态失败:', error);
    res.status(500).json({
      code: 500,
      message: '更新线索状态失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route PUT /api/admin/clues/:id
 * @desc 更新线索信息
 * @access Private (operator+)
 */
router.put('/clues/:id', authenticateToken, requireRole('operator'), async (req, res) => {
  try {
    const clueId = parseInt(req.params.id);
    const updateData = req.body;

    console.log('更新线索请求:', {
      clueId,
      updateData,
      method: req.method,
      url: req.url
    });

    const clue = await Clue.findById(clueId);
    if (!clue) {
      console.log('线索不存在:', clueId);
      return res.status(404).json({
        code: 404,
        message: '线索不存在',
        timestamp: Date.now()
      });
    }

    console.log('找到线索:', {
      id: clue.id,
      clue_no: clue.clue_no,
      current_priority: clue.priority
    });

    // 更新线索信息
    const success = await clue.update(updateData);

    console.log('更新结果:', { success, updateData });

    if (success) {
      // 记录操作日志
      const admin = await Admin.findById(req.admin.id);
      if (admin) {
        await admin.logAction('update_clue', 'clue', `更新线索信息: ${clue.clue_no}`, {
          clue_id: clueId,
          update_data: updateData,
          ip: req.ip
        });
      }

      res.json({
        code: 200,
        message: '线索信息更新成功',
        timestamp: Date.now()
      });
    } else {
      console.log('更新失败: success为false');
      res.status(500).json({
        code: 500,
        message: '线索信息更新失败',
        timestamp: Date.now()
      });
    }

  } catch (error) {
    console.error('更新线索信息失败:', error);
    res.status(500).json({
      code: 500,
      message: '更新线索信息失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route POST /api/admin/clues/batch
 * @desc 批量操作线索
 * @access Private (operator+)
 */
router.post('/clues/batch', authenticateToken, requireRole('operator'), [
  body('action').isIn(['update_status']).withMessage('无效的操作'),
  body('clue_ids').isArray().withMessage('线索ID列表不能为空'),
], async (req, res) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({
        code: 400,
        message: '参数验证失败',
        errors: errors.array(),
        timestamp: Date.now()
      });
    }

    const { action, clue_ids, data } = req.body;

    if (action === 'update_status') {
      const { status, handler_id } = data;
      const affectedRows = await Clue.batchUpdateStatus(clue_ids, status, handler_id);

      // 记录操作日志
      const admin = await Admin.findById(req.admin.id);
      if (admin) {
        await admin.logAction('batch_update_clue_status', 'clue', `批量更新线索状态`, {
          clue_ids,
          status,
          affected_rows: affectedRows,
          ip: req.ip
        });
      }

      res.json({
        code: 200,
        message: `成功更新 ${affectedRows} 条线索`,
        data: { affected_rows: affectedRows },
        timestamp: Date.now()
      });
    }

  } catch (error) {
    console.error('批量操作失败:', error);
    res.status(500).json({
      code: 500,
      message: '批量操作失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route GET /api/admin/clues/:id/processing-history
 * @desc 获取线索处理历史
 * @access Private (operator+)
 */
router.get('/clues/:id/processing-history', authenticateToken, requireRole('operator'), async (req, res) => {
  try {
    const clueId = parseInt(req.params.id);

    // 检查线索是否存在
    const clue = await Clue.findById(clueId);
    if (!clue) {
      return res.status(404).json({
        code: 404,
        message: '线索不存在',
        timestamp: Date.now()
      });
    }

    // 获取处理历史
    const historySql = `
      SELECT 
        cpl.id,
        cpl.action_type,
        cpl.old_value,
        cpl.new_value,
        cpl.processing_opinion,
        cpl.note,
        cpl.admin_name,
        cpl.ip_address,
        cpl.created_at,
        CASE 
          WHEN cpl.action_type = 'status_change' THEN '状态变更'
          WHEN cpl.action_type = 'priority_change' THEN '优先级变更'
          WHEN cpl.action_type = 'assignment' THEN '分配处理人'
          WHEN cpl.action_type = 'note_added' THEN '添加备注'
          WHEN cpl.action_type = 'file_uploaded' THEN '上传文件'
          ELSE cpl.action_type
        END as action_text
      FROM clue_processing_logs cpl
      WHERE cpl.clue_id = ?
      ORDER BY cpl.created_at DESC
      LIMIT 50
    `;

    const history = await db.query(historySql, [clueId]);

    // 格式化历史记录
    const formattedHistory = history.map(record => ({
      id: record.id,
      action_type: record.action_type,
      action_text: record.action_text,
      old_value: record.old_value,
      new_value: record.new_value,
      processing_opinion: record.processing_opinion,
      note: record.note,
      admin_name: record.admin_name,
      ip_address: record.ip_address,
      created_at: record.created_at,
      formatted_time: new Date(record.created_at).toLocaleString('zh-CN')
    }));

    res.json({
      code: 200,
      message: 'success',
      data: {
        clue_id: clueId,
        clue_no: clue.clue_no,
        total_records: formattedHistory.length,
        history: formattedHistory
      },
      timestamp: Date.now()
    });

  } catch (error) {
    console.error('获取处理历史失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取处理历史失败',
      timestamp: Date.now()
    });
  }
});

// ======================== 统计分析 ========================

/**
 * @route GET /api/admin/statistics/overview
 * @desc 获取数据概览
 * @access Private (operator+)
 */
router.get('/statistics/overview', authenticateToken, requireRole('operator'), async (req, res) => {
  try {
    const period = req.query.period || 'all';
    const overview = await Clue.getOverview(period);

    // 获取分类统计
    const categoryStats = await Clue.getStatistics({ groupBy: 'category' });

    // 获取地区统计（简化版）
    const regionStats = await db.query(`
      SELECT u.province as region, COUNT(c.id) as count
      FROM clues c
      LEFT JOIN users u ON c.user_id = u.id
      GROUP BY u.province
      ORDER BY count DESC
      LIMIT 10
    `);

    // 获取乡镇统计
    const townshipStats = await db.query(`
      SELECT 
        r.name as township_name,
        COUNT(c.id) as count
      FROM clues c
      LEFT JOIN users u ON c.user_id = u.id
      LEFT JOIN regions r ON u.district = r.name
      WHERE r.level = 3
      GROUP BY r.name
      ORDER BY count DESC
      LIMIT 20
    `);

    res.json({
      code: 200,
      message: 'success',
      data: {
        ...overview,
        category_stats: categoryStats,
        region_stats: regionStats,
        township_stats: townshipStats
      },
      timestamp: Date.now()
    });

  } catch (error) {
    console.error('获取数据概览失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取数据概览失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route GET /api/admin/statistics/trends
 * @desc 获取趋势数据
 * @access Private (operator+)
 */
router.get('/statistics/trends', authenticateToken, requireRole('operator'), async (req, res) => {
  try {
    const type = req.query.type || 'submission';
    const period = req.query.period || '7d';

    const dateStats = await Clue.getStatistics({
      groupBy: 'date',
      endDate: new Date(),
      startDate: new Date(Date.now() - (parseInt(period) * 24 * 60 * 60 * 1000))
    });

    const dates = dateStats.map(stat => stat.date);
    const values = dateStats.map(stat => stat.count);

    res.json({
      code: 200,
      message: 'success',
      data: {
        dates,
        values
      },
      timestamp: Date.now()
    });

  } catch (error) {
    console.error('获取趋势数据失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取趋势数据失败',
      timestamp: Date.now()
    });
  }
});

// ======================== 用户管理 ========================

/**
 * @route GET /api/admin/users
 * @desc 获取管理员列表
 * @access Private (admin+)
 */
router.get('/users', authenticateToken, requireRole('admin'), async (req, res) => {
  try {
    const options = {
      page: parseInt(req.query.page) || 1,
      pageSize: parseInt(req.query.page_size) || 20,
      role: req.query.role,
      isActive: req.query.is_active
    };

    const result = await Admin.getList(options);

    res.json({
      code: 200,
      message: 'success',
      data: result,
      timestamp: Date.now()
    });

  } catch (error) {
    console.error('获取管理员列表失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取管理员列表失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route POST /api/admin/users
 * @desc 创建管理员
 * @access Private (super_admin)
 */
router.post('/users', authenticateToken, requireRole('super_admin'), [
  body('username').isLength({ min: 3, max: 50 }).withMessage('用户名长度应在3-50字符之间'),
  body('password').isLength({ min: 6 }).withMessage('密码长度至少6个字符'),
  body('real_name').notEmpty().withMessage('真实姓名不能为空'),
  body('role').isIn(['super_admin', 'admin', 'operator', 'viewer']).withMessage('无效的角色')
], async (req, res) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({
        code: 400,
        message: '参数验证失败',
        errors: errors.array(),
        timestamp: Date.now()
      });
    }

    const adminData = {
      ...req.body,
      created_by: req.admin.id
    };

    const admin = new Admin(adminData);
    await admin.create();

    // 记录操作日志
    const creator = await Admin.findById(req.admin.id);
    if (creator) {
      await creator.logAction('create_admin', 'user', `创建管理员: ${admin.username}`, {
        new_admin_id: admin.id,
        ip: req.ip
      });
    }

    res.status(201).json({
      code: 200,
      message: '管理员创建成功',
      data: admin.getSafeInfo(),
      timestamp: Date.now()
    });

  } catch (error) {
    console.error('创建管理员失败:', error);
    res.status(500).json({
      code: 500,
      message: error.message || '创建管理员失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route PUT /api/admin/users/:id
 * @desc 更新管理员信息
 * @access Private (admin+, 自己)
 */
router.put('/users/:id', authenticateToken, requireRole('admin'), requireSelfOrSuperAdmin, async (req, res) => {
  try {
    const adminId = parseInt(req.params.id);
    const admin = await Admin.findById(adminId);

    if (!admin) {
      return res.status(404).json({
        code: 404,
        message: '管理员不存在',
        timestamp: Date.now()
      });
    }

    const success = await admin.update(req.body);

    if (success) {
      res.json({
        code: 200,
        message: '更新成功',
        data: admin.getSafeInfo(),
        timestamp: Date.now()
      });
    } else {
      res.status(500).json({
        code: 500,
        message: '更新失败',
        timestamp: Date.now()
      });
    }

  } catch (error) {
    console.error('更新管理员失败:', error);
    res.status(500).json({
      code: 500,
      message: error.message || '更新管理员失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route POST /api/admin/users/:id/reset-password
 * @desc 重置密码
 * @access Private (super_admin)
 */
router.post('/users/:id/reset-password', authenticateToken, requireRole('super_admin'), [
  body('new_password').isLength({ min: 6 }).withMessage('密码长度至少6个字符')
], async (req, res) => {
  try {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({
        code: 400,
        message: '参数验证失败',
        errors: errors.array(),
        timestamp: Date.now()
      });
    }

    const adminId = parseInt(req.params.id);
    const { new_password } = req.body;

    const admin = await Admin.findById(adminId);
    if (!admin) {
      return res.status(404).json({
        code: 404,
        message: '管理员不存在',
        timestamp: Date.now()
      });
    }

    const success = await admin.resetPassword(new_password);

    if (success) {
      res.json({
        code: 200,
        message: '密码重置成功',
        timestamp: Date.now()
      });
    } else {
      res.status(500).json({
        code: 500,
        message: '密码重置失败',
        timestamp: Date.now()
      });
    }

  } catch (error) {
    console.error('重置密码失败:', error);
    res.status(500).json({
      code: 500,
      message: '重置密码失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route GET /api/admin/users/:id
 * @desc 获取指定管理员信息
 * @access Private (admin+, 仅本人或超级管理员)
 */
router.get('/users/:id', authenticateToken, requireRole('admin'), requireSelfOrSuperAdmin, async (req, res) => {
  try {
    const adminId = parseInt(req.params.id);
    const admin = await Admin.findById(adminId);
    if (!admin) {
      return res.status(404).json({
        code: 404,
        message: '管理员不存在',
        timestamp: Date.now()
      });
    }
    res.json({
      code: 200,
      message: 'success',
      data: admin.getSafeInfo(),
      timestamp: Date.now()
    });
  } catch (error) {
    console.error('获取管理员信息失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取管理员信息失败',
      timestamp: Date.now()
    });
  }
});

// ======================== 系统设置 ========================

/**
 * @route GET /api/admin/settings
 * @desc 获取系统配置
 * @access Private (admin+)
 */
router.get('/settings', authenticateToken, requireRole('admin'), async (req, res) => {
  try {
    const settings = await db.findMany('system_settings');

    const settingsObj = {};
    settings.forEach(setting => {
      let value = setting.setting_value;

      switch (setting.setting_type) {
        case 'number':
          value = parseFloat(value);
          break;
        case 'boolean':
          value = value === '1' || value === 'true';
          break;
        case 'json':
          try {
            value = JSON.parse(value);
          } catch (e) {
            value = setting.setting_value;
          }
          break;
      }

      settingsObj[setting.setting_key] = {
        value,
        type: setting.setting_type,
        group: setting.group_name,
        description: setting.description,
        is_public: setting.is_public
      };
    });

    res.json({
      code: 200,
      message: 'success',
      data: settingsObj,
      timestamp: Date.now()
    });

  } catch (error) {
    console.error('获取系统配置失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取系统配置失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route GET /api/admin/logs
 * @desc 获取操作日志
 * @access Private (admin+)
 */
router.get('/logs', authenticateToken, requireRole('admin'), async (req, res) => {
  try {
    const options = {
      page: parseInt(req.query.page) || 1,
      pageSize: parseInt(req.query.page_size) || 20,
      adminId: req.query.admin_id,
      action: req.query.action,
      module: req.query.module,
      startDate: req.query.start_date,
      endDate: req.query.end_date
    };

    const result = await Admin.getLogs(options);

    res.json({
      code: 200,
      message: 'success',
      data: result,
      timestamp: Date.now()
    });

  } catch (error) {
    console.error('获取操作日志失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取操作日志失败',
      timestamp: Date.now()
    });
  }
});

// ======================== 静态文件服务 ========================

/**
 * @route GET /api/admin/login.html
 * @desc 获取登录页面
 * @access Public
 */
router.get('/login.html', (req, res) => {
  res.sendFile(path.join(__dirname, '../admin/login.html'));
});

/**
 * @route GET /api/admin/dashboard
 * @desc 获取管理后台页面
 * @access Public
 */
router.get('/dashboard', (req, res) => {
  res.sendFile(path.join(__dirname, '../admin/dashboard.html'));
});

// ======================== 下载附件 ========================

/**
 * @route GET /api/admin/attachments/:id/download
 * @desc 下载附件
 * @access Public
 */
router.get('/attachments/:id/download', async (req, res) => {
  try {
    const { id } = req.params;
    const attachments = await db.query(
      'SELECT * FROM attachments WHERE id = ? AND is_deleted = 0',
      [id]
    );

    if (attachments.length === 0) {
      return res.status(404).json({
        code: 404,
        message: '附件不存在',
        timestamp: Date.now()
      });
    }

    const attachment = attachments[0];
    const filePath = path.join(__dirname, '../', attachment.file_path);

    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
      return res.status(404).json({
        code: 404,
        message: '文件不存在',
        timestamp: Date.now()
      });
    }

    res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(attachment.file_name)}"`);
    res.setHeader('Content-Type', attachment.file_type);
    res.sendFile(filePath);

  } catch (error) {
    console.error('下载附件失败:', error);
    res.status(500).json({
      code: 500,
      message: '下载失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route GET /api/admin/attachments/:id/view
 * @desc 查看附件（支持在线预览）
 * @access Public
 */
router.get('/attachments/:id/view', async (req, res) => {
  try {
    const { id } = req.params;
    const attachments = await db.query(
      'SELECT * FROM attachments WHERE id = ? AND is_deleted = 0',
      [id]
    );

    if (attachments.length === 0) {
      return res.status(404).json({
        code: 404,
        message: '附件不存在',
        timestamp: Date.now()
      });
    }

    const attachment = attachments[0];
    const filePath = path.join(__dirname, '../', attachment.file_path);

    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
      return res.status(404).json({
        code: 404,
        message: '文件不存在',
        timestamp: Date.now()
      });
    }

    // 设置适当的Content-Type和缓存头
    res.setHeader('Content-Type', attachment.file_type);
    res.setHeader('Content-Length', attachment.file_size);
    res.setHeader('Cache-Control', 'public, max-age=86400'); // 缓存1天
    res.setHeader('Last-Modified', new Date(attachment.upload_time).toUTCString());

    // 对于图片、音频、视频等媒体文件，设置为inline显示
    const mediaTypes = ['image/', 'audio/', 'video/', 'application/pdf'];
    const isMediaFile = mediaTypes.some(type => attachment.file_type.startsWith(type));

    if (isMediaFile) {
      res.setHeader('Content-Disposition', `inline; filename="${encodeURIComponent(attachment.file_name)}"`);
    } else {
      res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(attachment.file_name)}"`);
    }

    // 支持范围请求（用于视频流等）
    const range = req.headers.range;
    if (range && attachment.file_type.startsWith('video/')) {
      const parts = range.replace(/bytes=/, "").split("-");
      const start = parseInt(parts[0], 10);
      const end = parts[1] ? parseInt(parts[1], 10) : attachment.file_size - 1;
      const chunksize = (end - start) + 1;

      res.status(206);
      res.setHeader('Content-Range', `bytes ${start}-${end}/${attachment.file_size}`);
      res.setHeader('Accept-Ranges', 'bytes');
      res.setHeader('Content-Length', chunksize);

      const stream = fs.createReadStream(filePath, { start, end });
      stream.pipe(res);
    } else {
      res.sendFile(filePath);
    }

    // 记录查看日志（可选，去掉 req.user）
    // if (req.user) {
    //   await req.user.logAction('view', 'attachment', `查看附件: ${attachment.file_name}`, {
    //     attachment_id: id,
    //     file_name: attachment.file_name,
    //     file_type: attachment.file_type
    //   });
    // }

  } catch (error) {
    console.error('查看附件失败:', error);
    res.status(500).json({
      code: 500,
      message: '查看失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route GET /api/admin/attachments/:id/info
 * @desc 获取附件信息
 * @access Private (operator+)
 */
router.get('/attachments/:id/info', authenticateToken, async (req, res) => {
  try {
    const { id } = req.params;
    const attachments = await db.query(`
      SELECT a.*, c.clue_no, c.title as clue_title
      FROM attachments a
      LEFT JOIN clues c ON a.clue_id = c.id
      WHERE a.id = ? AND a.is_deleted = 0
    `, [id]);

    if (attachments.length === 0) {
      return res.status(404).json({
        code: 404,
        message: '附件不存在',
        timestamp: Date.now()
      });
    }

    const attachment = attachments[0];
    const filePath = path.join(__dirname, '../', attachment.file_path);

    // 检查文件是否存在
    const fileExists = fs.existsSync(filePath);

    // 获取文件统计信息
    let fileStats = null;
    if (fileExists) {
      try {
        fileStats = fs.statSync(filePath);
      } catch (error) {
        console.error('获取文件统计信息失败:', error);
      }
    }

    // 判断文件类型
    const isImage = attachment.file_type.startsWith('image/');
    const isAudio = attachment.file_type.startsWith('audio/');
    const isVideo = attachment.file_type.startsWith('video/');
    const isPdf = attachment.file_type === 'application/pdf';
    const isDocument = ['application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
                       'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'].includes(attachment.file_type);

    res.json({
      code: 200,
      data: {
        id: attachment.id,
        clue_id: attachment.clue_id,
        clue_no: attachment.clue_no,
        clue_title: attachment.clue_title,
        file_name: attachment.file_name,
        original_name: attachment.file_name,
        file_path: attachment.file_path,
        file_size: attachment.file_size,
        file_type: attachment.file_type,
        file_extension: attachment.file_extension,
        upload_time: attachment.upload_time,
        upload_ip: attachment.upload_ip,
        file_exists: fileExists,
        actual_size: fileStats ? fileStats.size : null,
        last_modified: fileStats ? fileStats.mtime : null,
        // 文件类型判断
        is_image: isImage,
        is_audio: isAudio,
        is_video: isVideo,
        is_pdf: isPdf,
        is_document: isDocument,
        can_preview: isImage || isAudio || isVideo || isPdf,
        // 预览和下载URL
        view_url: `/api/admin/attachments/${id}/view`,
        download_url: `/api/admin/attachments/${id}/download`,
        thumbnail_url: isImage ? `/api/admin/attachments/${id}/thumbnail` : null
      },
      timestamp: Date.now()
    });

  } catch (error) {
    console.error('获取附件信息失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取附件信息失败',
      timestamp: Date.now()
    });
  }
});

/**
 * @route GET /api/admin/attachments/:id/thumbnail
 * @desc 获取图片缩略图
 * @access Private (operator+)
 */
router.get('/attachments/:id/thumbnail', authenticateToken, async (req, res) => {
  try {
    const { id } = req.params;
    const { size = '200' } = req.query; // 缩略图大小
    const attachments = await db.query(
      'SELECT * FROM attachments WHERE id = ? AND is_deleted = 0',
      [id]
    );

    if (attachments.length === 0) {
      return res.status(404).json({
        code: 404,
        message: '附件不存在',
        timestamp: Date.now()
      });
    }

    const attachment = attachments[0];

    // 只处理图片文件
    if (!attachment.file_type.startsWith('image/')) {
      return res.status(400).json({
        code: 400,
        message: '该文件不是图片',
        timestamp: Date.now()
      });
    }

    const filePath = path.join(__dirname, '../', attachment.file_path);

    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
      return res.status(404).json({
        code: 404,
        message: '文件不存在',
        timestamp: Date.now()
      });
    }

    // 简单的缩略图处理（实际项目中可以使用sharp等库）
    res.setHeader('Content-Type', attachment.file_type);
    res.setHeader('Cache-Control', 'public, max-age=604800'); // 缓存7天
    res.sendFile(filePath);

  } catch (error) {
    console.error('获取缩略图失败:', error);
    res.status(500).json({
      code: 500,
      message: '获取缩略图失败',
      timestamp: Date.now()
    });
  }
});

module.exports = router;
